//! Rust 时间类型分类与选择
//!
//! | 类型                      | 所属库    | 作用/描述                      | 使用场景                   | 是否带时区 | 格式化支持 | 推荐场景 |
//! |---------------------------|-----------|-------------------------------|----------------------------|------------|------------|----------|
//! | std::time::SystemTime     | 标准库     | 系统时间点，UNIX时间戳         | 文件时间戳、系统API         | 否         | 否         | 系统层面 |
//! | std::time::Instant        | 标准库     | 高精度计时器，仅测间隔         | 性能分析、计时              | 否         | 否         | 计时     |
//! | std::time::Duration       | 标准库     | 时间长度（秒、毫秒等）         | 超时、sleep、计时           | 否         | 否         | 计时     |
//! | chrono::Local             | chrono     | 本地时区时间                   | 用户界面、日志              | 是         | 是         | 本地化   |
//! | chrono::Utc               | chrono     | 世界标准时间                   | 跨时区、存储、协议          | 是         | 是         | 通用     |
//! | `chrono::DateTime<Tz>`      | chrono     | 带时区的日期时间               | 国际化、API、日志           | 是         | 是         | 通用     |
//! | chrono::NaiveDateTime     | chrono     | 不带时区的日期时间             | 数据库、简单时间计算         | 否         | 是         | 计算     |
//! | chrono::NaiveDate         | chrono     | 仅日期（无时区）               | 生日、日期字段              | 否         | 是         | 计算     |
//! | chrono::NaiveTime         | chrono     | 仅时间（无时区）               | 每天某时刻                  | 否         | 是         | 计算     |
//! | chrono::FixedOffset       | chrono     | 固定时区偏移                   | 特定时区处理                | 是         | 是         | 时区运算 |
//! | chrono::Weekday           | chrono     | 星期几                         | 日期运算                    | 否         | 是         | 计算     |
//! | chrono::Duration          | chrono     | 时间段                         | 加减运算、间隔              | 否         | 是         | 计算     |
//!
//! 选择建议：
//! - 仅做计时/超时/性能分析用标准库类型（Instant/Duration）。
//! - 需处理具体日期时间建议用 chrono 类型（DateTime/Local/Utc/NaiveDateTime）。
//! - 需时区转换或国际化建议用 `DateTime<Utc>` 或 `DateTime<Local>`。
//! - 仅做时间计算或数据库字段可用 NaiveDateTime/NaiveDate/NaiveTime。
//! - 系统层面如文件时间戳用 SystemTime。
//! - 复杂时区运算用 FixedOffset。

use chrono::{DateTime, Datelike, Local, Utc};

#[test]
fn std_system_time_demo() {
    use std::time::SystemTime;
    let sys_time = SystemTime::now();
    println!("SystemTime: {sys_time:?}");
    match sys_time.duration_since(SystemTime::UNIX_EPOCH) {
        Ok(dur) => println!("自UNIX纪元秒数: {}", dur.as_secs()),
        Err(e) => println!("时间早于UNIX纪元: {:?}", e),
    }
}

#[test]
fn std_instant_duration_demo() {
    use std::time::{Duration, Instant};
    let start = Instant::now();
    let d = Duration::from_millis(500);
    std::thread::sleep(d);
    let elapsed = start.elapsed();
    println!("计时器已过去: {}ms", elapsed.as_millis());
}

#[test]
fn chrono_local_utc_demo() {
    let local_time = Local::now();
    let utc_time = Utc::now();
    println!("Local时间: {}", local_time);
    println!("UTC时间: {}", utc_time);
}

#[test]
fn chrono_datetime_demo() {
    let local_time = Local::now();
    let utc_time = Utc::now();
    let dt_local: DateTime<Local> = local_time;
    let dt_utc: DateTime<Utc> = utc_time;
    println!("DateTime<Local>: {}", dt_local);
    println!("DateTime<Utc>: {}", dt_utc);
    // 互转
    let utc_from_local = dt_local.with_timezone(&Utc);
    println!("Local转UTC: {}", utc_from_local);
    let local_from_utc = dt_utc.with_timezone(&Local);
    println!("UTC转Local: {}", local_from_utc);
}

#[test]
fn chrono_naive_demo() {
    let local_time = Local::now();
    let naive_dt = local_time.naive_local();
    let naive_date = naive_dt.date();
    let naive_time = naive_dt.time();
    println!("NaiveDateTime: {}", naive_dt);
    println!("NaiveDate: {}", naive_date);
    println!("NaiveTime: {}", naive_time);
}

#[test]
fn chrono_fixedoffset_demo() {
    use chrono::FixedOffset;
    let offset = FixedOffset::east_opt(8 * 3600).unwrap();
    let dt = Utc::now().with_timezone(&offset);
    println!("FixedOffset(+8): {}", dt);
}

#[test]
fn chrono_weekday_demo() {
    let today = Local::now().date_naive();
    let weekday = today.weekday();
    println!("今天是星期: {:?}", weekday);
}

#[test]
fn chrono_duration_demo() {
    use chrono::Duration;
    let now = Local::now();
    let after = now + Duration::days(1);
    println!("现在: {}，一天后: {}", now, after);
    let diff = after - now;
    println!("时间差: {}秒", diff.num_seconds());
}

#[test]
fn chrono_format_parse_demo() {
    let now = Local::now();
    let fmt = DateTimeFormatEnum::DateTimeWithTimezone.pattern().unwrap();
    let s = now.format(fmt).to_string();
    println!("格式化: {}", s);
    let parsed = chrono::DateTime::parse_from_str(&s, fmt).unwrap();
    println!("解析: {}", parsed);
}
// 日期格式枚举
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum DateTimeFormatEnum {
    /// 仅时间格式: %H:%M (例如 "14:30")
    Time,
    /// 完整日期时间格式: %Y-%m-%d %H:%M:%S (例如 "2023-01-15 14:30:00")
    DateTime,
    /// 紧凑型日期时间格式: %Y%m%d%H%M%S (例如 "20230115143000")
    DateTimeStr,
    /// 年-月-日格式: %Y-%m-%d (例如 "2023-01-15")
    Year,
    /// 无分隔符日期格式: %Y%m%d (例如 "20230115")
    YearNoSplit,
    /// 紧凑型时间格式: %H%M%S (例如 "143000")
    DateTimePattern,
    /// 带时区的完整日期时间格式: %Y-%m-%d %H:%M:%S %:z (例如 "2023-01-15 14:30:00 +08:00")
    DateTimeWithTimezone,
    /// 仅日期（无时间）: %Y-%m-%d (例如 "2023-01-15")
    DateOnly,
    /// 仅时间（无日期）: %H:%M:%S (例如 "14:30:00")
    TimeOnly,
    /// ISO 8601 标准格式（带时区）: %Y-%m-%dT%H:%M:%S%:z (例如 "2023-01-15T14:30:00+08:00")
    Iso8601,
    /// RFC 2822 格式: %a, %d %b %Y %H:%M:%S %z (例如 "Tue, 15 Jan 2023 14:30:00 +0800")
    Rfc2822,
    /// RFC 3339 格式: %Y-%m-%dT%H:%M:%S%.f%:z (例如 "2023-01-15T14:30:00.123+08:00")
    Rfc3339,
    /// 中文日期格式: %Y年%m月%d日 %H时%M分%S秒 (例如 "2023年01月15日 14时30分00秒")
    Chinese,
}

impl DateTimeFormatEnum {
    /// 获取日期时间格式的字符串模式
    ///
    /// # 返回值
    ///
    /// 返回与枚举值对应的日期时间格式字符串模式
    pub const fn pattern(&self) -> Option<&'static str> {
        match self {
            DateTimeFormatEnum::Time => Some("%H:%M"),
            DateTimeFormatEnum::DateTime => Some("%Y-%m-%d %H:%M:%S"),
            DateTimeFormatEnum::DateTimeStr => Some("%Y%m%d%H%M%S"),
            DateTimeFormatEnum::Year => Some("%Y-%m-%d"),
            DateTimeFormatEnum::YearNoSplit => Some("%Y%m%d"),
            DateTimeFormatEnum::DateTimePattern => Some("%H%M%S"),
            DateTimeFormatEnum::DateTimeWithTimezone => Some("%Y-%m-%d %H:%M:%S %:z"),
            DateTimeFormatEnum::DateOnly => Some("%Y-%m-%d"),
            DateTimeFormatEnum::TimeOnly => Some("%H:%M:%S"),
            DateTimeFormatEnum::Iso8601 => Some("%Y-%m-%dT%H:%M:%S%:z"),
            DateTimeFormatEnum::Rfc2822 => Some("%a, %d %b %Y %H:%M:%S %z"),
            DateTimeFormatEnum::Rfc3339 => Some("%Y-%m-%dT%H:%M:%S%.f%:z"),
            DateTimeFormatEnum::Chinese => Some("%Y年%m月%d日 %H时%M分%S秒"),
        }
    }
}
